package com.os.core.datasource;

import com.os.common.entity.datasource.DataSource;
import com.os.common.exception.DataSourceNotFoundException;
import com.os.system.service.DataSourceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.sql.SQLException;
import java.util.List;

/**
 * 描述：切换数据源实现类
 *
 * @author huxuehao
 **/
@Service
public class DBChangeService {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private final DataSourceService dataSourceService;
    private final DynamicDataSource dynamicDataSource;

    public DBChangeService(DataSourceService dataSourceService, DynamicDataSource dynamicDataSource) {
        this.dataSourceService = dataSourceService;
        this.dynamicDataSource = dynamicDataSource;
    }

    public List<DataSource> get() throws SQLException {
        return dataSourceService.selectList();
    }

    public void clearDSCache() {
        DataSourceConfigCache.deleteAll();
        dynamicDataSource.clearDSCache();
    }
    /**
     * 切换到默认数据源
     */
    public void changeDefaultBD() {
        /* 默认切换到主数据源，进行整体资源的查找*/
        DBContextHolder.clearDataSource();
    }

    /**
     * 切换数据源
     * @param datasourceId 目标数据源key
     */
    public boolean changeBD(String datasourceId) {
        /* 刷新缓存*/
        refreshCache(datasourceId);
        /* 获取数据配置*/
        DataSource dataSource = DataSourceConfigCache.get(datasourceId);
        if (dynamicDataSource.createDataSourceWithCheck(dataSource)) {
            /* 切换数据源 */
            DBContextHolder.clearDataSource();
            DBContextHolder.setDataSource(String.valueOf(dataSource.getId()));
            return true;
        }
        log.error("[{}]数据源切换失败",dataSource.getName());
        return false;
    }

    /**
     * 刷新缓存
     * @param datasourceId 数据源key
     */
    private void refreshCache(String datasourceId) {
        if (DataSourceConfigCache.exist(datasourceId)) {
            return;
        }
        try {
            DataSource dataSource = dataSourceService.selectById(datasourceId);
            if (dataSource == null) {
                throw new DataSourceNotFoundException();
            }
            DataSourceConfigCache.put(dataSource);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }


}
